from flask import Flask, render_template, request, jsonify, redirect
from flask_socketio import SocketIO, emit, join_room, leave_room, disconnect
import json
from functools import wraps
from datetime import datetime
import os
# 导入小猫聊天模块
import cat_chat

app = Flask(__name__, static_folder='static', static_url_path='/static')
app.config['SECRET_KEY'] = 'secret!'
app.config['STATIC_FOLDER'] = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
socketio = SocketIO(app)

# 注册小猫聊天模块
cat_chat.init_app(app)

# 存储在线用户
online_users = {}
# 存储消息计数
message_count = 0

# 用户信息存储
users = {
    'admin': {
        'password': '123456',
        'is_admin': True,
        'avatar': 'default'
    },
    '就喜欢偷偷的看':{
        'password': '123456',
        'is_admin': False,
        'avatar': 'fish.png'
    },
    '哥不是娘炮':{
        'password': '123456',
        'is_admin': False,
        'avatar': 'tiger1.png'
    },
    '地表最强虎哥':{
        'password': '123456',
        'is_admin': False,
        'avatar': 'tiger'
    },
    'test':{
        'password': '123456',
        'is_admin': False,
        'avatar': 'default'
    }
}

# 聊天室信息存储
chat_rooms = {
    'room1': {
        'name': '聊天室1',
        'created_by': 'admin',
        'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'description': '****被你发现了！**********'
    }
}

# 存储管理员的会话ID
admin_sessions = {}

@app.route('/')
def index():
    return render_template('login.html')

@app.route('/register')
def register_page():
    return render_template('register.html')

@app.route('/rooms')
def rooms_page():
    return render_template('chat.html')

@app.route('/admin')
def admin():
    token = request.args.get('token')
    if token != '123456':
        return redirect('/')
    return render_template('admin.html')

# 房间管理API
@app.route('/api/rooms', methods=['GET'])
def get_rooms():
    return jsonify({
        'success': True,
        'rooms': chat_rooms
    })

@app.route('/api/rooms', methods=['POST'])
def create_room():
    data = request.get_json()
    room_id = data.get('room_id')
    room_name = data.get('name')
    description = data.get('description')
    created_by = data.get('username')
    
    if not room_id or not room_name or not created_by:
        return jsonify({'success': False, 'message': '请填写所有必填字段'})
    
    if room_id in chat_rooms:
        return jsonify({'success': False, 'message': '房间ID已存在'})
    
    # 验证创建者是否为管理员
    user = users.get(created_by)
    if not user or not user.get('is_admin'):
        return jsonify({'success': False, 'message': '只有管理员可以创建房间'})
    
    from datetime import datetime
    chat_rooms[room_id] = {
        'name': room_name,
        'created_by': created_by,
        'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'description': description or ''
    }
    
    # 广播房间列表更新
    socketio.emit('rooms_update', chat_rooms)
    
    return jsonify({
        'success': True,
        'message': '房间创建成功',
        'room': chat_rooms[room_id]
    })

@app.route('/api/rooms/<room_id>', methods=['DELETE'])
def delete_room(room_id):
    username = request.args.get('username')
    
    # 验证用户是否为管理员
    user = users.get(username)
    if not user or not user.get('is_admin'):
        return jsonify({'success': False, 'message': '只有管理员可以删除房间'})
    
    if room_id not in chat_rooms:
        return jsonify({'success': False, 'message': '房间不存在'})
    
    # 如果房间中有用户，将他们踢出
    if room_id in online_users:
        for sid, username in online_users[room_id].items():
            emit('kicked', {'message': '该房间已被管理员删除'}, room=sid)
        del online_users[room_id]
    
    del chat_rooms[room_id]
    
    # 广播房间列表更新
    socketio.emit('rooms_update', chat_rooms)
    
    return jsonify({
        'success': True,
        'message': '房间删除成功'
    })

# 用户认证相关的API
@app.route('/api/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    
    if not username or not password:
        return jsonify({'success': False, 'message': '请填写用户名和密码'})
    
    user = users.get(username)
    if user and user['password'] == password:
        return jsonify({
            'success': True,
            'is_admin': user.get('is_admin', False),
            'username': username,
            'avatar': user['avatar'],
            'rooms': chat_rooms
        })
    
    return jsonify({'success': False, 'message': '用户名或密码错误'})

@app.route('/api/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    avatar = data.get('avatar')
    
    if not username or not password:
        return jsonify({'success': False, 'message': '请填写所有字段'})
    
    if username == 'admin':
        return jsonify({'success': False, 'message': '不能使用admin作为用户名'})
    
    if username in users:
        return jsonify({'success': False, 'message': '用户名已存在'})
    
    users[username] = {
        'password': password,
        'is_admin': False,
        'avatar': avatar
    }
    
    return jsonify({'success': True, 'message': '注册成功'})

# 用户管理API
@app.route('/api/users', methods=['GET'])
def get_users():
    token = request.args.get('token')
    if token != '123456':
        return jsonify({'success': False, 'message': '未授权的访问'}), 401
    
    return jsonify({
        'success': True,
        'users': users
    })

# WebSocket事件处理
@socketio.on('connect')
def handle_connect():
    print('Client connected')
    # 检查是否是管理员连接
    auth = request.args.get('auth')
    if auth == '123456':  # 使用与管理员token相同的验证
        admin_sessions[request.sid] = {'username': 'admin'}
        # 发送现有消息历史给管理员
        emit('admin_update', get_admin_data())
        emit('message_count_update', message_count)

@socketio.on('disconnect')
def handle_disconnect():
    # 如果是管理员断开连接，从管理员会话中移除
    if request.sid in admin_sessions:
        del admin_sessions[request.sid]
    
    # 处理普通用户断开连接
    for room in online_users:
        if online_users[room].get(request.sid):
            user_data = online_users[room][request.sid]
            username = user_data['username']
            del online_users[room][request.sid]
            # 发送更新的用户列表
            room_users = {sid: user_data for sid, user_data in online_users[room].items()}
            emit('user_left', {
                'username': username,
                'users': room_users
            }, room=room)
            # 发送更新到管理员
            emit('admin_update', get_admin_data(), broadcast=True)
    print('Client disconnected')

@socketio.on('join')
def handle_join(data):
    username = data['username']
    room = data['room']
    
    # 先离开之前的房间（如果有的话）
    if room in online_users:
        for sid, user_data in list(online_users[room].items()):
            if user_data['username'] == username:
                del online_users[room][sid]
                leave_room(room, sid)
    
    join_room(room)
    if room not in online_users:
        online_users[room] = {}
    
    # 获取用户完整信息
    user_info = users.get(username, {})
    online_users[room][request.sid] = {
        'username': username,
        'avatar': user_info.get('avatar', 'default')
    }
    
    # 发送包含在线用户列表的加入消息
    room_users = {sid: user_data for sid, user_data in online_users[room].items()}
    emit('user_joined', {
        'username': username,
        'users': room_users
    }, room=room)
    emit('message', {
        'username': 'System',
        'message': f'欢迎 {username} 来到聊天室',
        'room': room
    }, room=room)
    # 发送更新到管理员
    emit('admin_update', get_admin_data(), broadcast=True)

@socketio.on('leave')
def handle_leave(data):
    username = data['username']
    room = data['room']
    
    leave_room(room)
    if room in online_users and request.sid in online_users[room]:
        user_data = online_users[room][request.sid]
        del online_users[room][request.sid]
        # 发送包含在线用户列表的离开消息
        emit('user_left', {
            'username': username,
            'users': {sid: user_data for sid, user_data in online_users.get(room, {}).items()}
        }, room=room)
        emit('message', {
            'username': 'System',
            'message': f'{username} 离开聊天室',
            'room': room
        }, room=room)
        # 发送更新到管理员
        emit('admin_update', get_admin_data(), broadcast=True)

@socketio.on('message')
def handle_message(data):
    global message_count
    username = data['username']
    room = data['room']
    message = data['message']
    message_count += 1
    
    # 获取用户头像信息
    user_info = users.get(username, {})
    avatar = user_info.get('avatar', 'default')
    
    # 添加房间信息和头像信息到消息数据中
    message_data = {
        'username': username,
        'message': message,
        'room': room,
        'timestamp': datetime.now().strftime('%H:%M:%S'),
        'avatar': avatar
    }
    
    # 发送消息到房间
    emit('message', message_data, room=room)
    # 发送消息到所有管理员
    for sid, user_data in admin_sessions.items():
        emit('message', message_data, room=sid)
    # 发送消息计数更新到管理员
    emit('message_count_update', message_count, broadcast=True)

@socketio.on('private_message')
def handle_private_message(data):
    to_username = data['to']
    from_username = data['from']
    message = data['message']
    chat_id = data['chatId']
    
    # 获取发送者的头像信息
    from_user = users.get(from_username, {})
    from_avatar = from_user.get('avatar', 'default')
    
    # 获取接收者的会话ID
    to_sid = None
    for room in online_users.values():
        for sid, user_data in room.items():
            if user_data['username'] == to_username:
                to_sid = sid
                break
        if to_sid:
            break
    
    # 构建消息数据
    message_data = {
        'from': from_username,
        'to': to_username,
        'message': message,
        'chatId': chat_id,
        'timestamp': datetime.now().strftime('%H:%M:%S'),
        'fromAvatar': from_avatar
    }
    
    # 发送消息给接收者
    if to_sid:
        emit('private_message', message_data, room=to_sid)
    
    # 发送消息给发送者（如果不是来自同一个会话）
    if request.sid != to_sid:
        emit('private_message', message_data, room=request.sid)

# 管理员相关的WebSocket事件
@socketio.on('admin_request_update')
def handle_admin_request_update():
    emit('admin_update', get_admin_data())
    emit('message_count_update', message_count)

@socketio.on('admin_kick_user')
def handle_admin_kick_user(data):
    room = data['room']
    sid = data['sid']
    username = data['username']
    
    if room in online_users and sid in online_users[room]:
        user_data = online_users[room][sid]
        # 发送踢出消息给被踢用户
        emit('kicked', {'message': '您已被管理员踢出聊天室'}, room=sid)
        # 从房间中移除用户
        del online_users[room][sid]
        # 通知房间其他用户
        emit('message', {
            'username': 'System',
            'message': f'{username} 被管理员踢出聊天室',
            'room': room
        }, room=room)
        # 更新在线用户列表
        emit('user_left', {
            'username': username,
            'users': {sid: user_data for sid, user_data in online_users.get(room, {}).items()}
        }, room=room)
        # 断开用户连接
        leave_room(room, sid)
        # 发送更新到管理员
        emit('admin_update', get_admin_data(), broadcast=True)

def get_admin_data():
    # 返回包含聊天室信息和在线用户信息的数据
    admin_data = {}
    for room_id, room_info in chat_rooms.items():
        admin_data[room_id] = {
            'name': room_info['name'],
            'created_by': room_info['created_by'],
            'created_at': room_info['created_at'],
            'description': room_info['description'],
            'users': online_users.get(room_id, {})
        }
    return admin_data

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000, debug=True) 